package com.hh.ui.view;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.text.Editable;
import android.text.Html;
import android.text.Selection;
import android.text.Spannable;
import android.text.Spanned;
import android.text.TextWatcher;
import android.text.style.CharacterStyle;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.text.style.UnderlineSpan;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Spinner;

import com.hh.droid.R;
import com.hh.listeners.OnColorPickChangedListener;
import com.hh.ui.dialog.UiDialogColorPicker;

	public class DroidWriterView extends EditText {

		// Log tag
		public static final String TAG = "RicheText";

		// Style constants
		private static final int STYLE_BOLD = 0;
		private static final int STYLE_ITALIC = 1;
		private static final int STYLE_UNDERLINED = 2;
		private static final int STYLE_COLRED = 3;


		private Button _mButtonTextBold;
		private Button _mButtonTextItalic;
		private Button _mButtonTextUnderLine;
		private Button _mButtonColor;
		private LinearLayout _myLayoutColor;
		private Spinner _mSpinnerTextSize;
		private boolean _myIsSizeChaged;
		private boolean _myIsTextBoldSelected;
		private boolean _myIsTextItalicSelected;
		private boolean _myIsTextUnderLineSelected;
		private boolean _myIsTextColorSelected;

		@SuppressWarnings("unused")
		private int _myTextSize;
		private int _myTextColor;
		private Context _myContext;
		private Resources _myRes;
		private UiDialogColorPicker _mDialogColorPicker;


		public DroidWriterView(Context context) {
			super(context);
			initialize(context);
		}

		public DroidWriterView(Context context, AttributeSet attrs) {
			super(context, attrs);
			initialize(context);
		}

		public DroidWriterView(Context context, AttributeSet attrs, int defStyle) {
			super(context, attrs, defStyle);
			initialize(context);
		}

		private void initialize(Context pContext) {

			_myContext=pContext;
			_myRes=pContext.getResources();
			_myTextColor=Color.BLACK;

			_mDialogColorPicker=new UiDialogColorPicker(pContext);
			_mDialogColorPicker.setColor(_myTextColor);
			
			this.addTextChangedListener(new DWTextWatcher());
			this.setOnKeyListener(new View.OnKeyListener() {
				@Override
				public boolean onKey(View v, int keyCode, KeyEvent event) {

					if (keyCode == KeyEvent.KEYCODE_DEL) {
						_myIsSizeChaged=false;
					}
					return false;
				}
			});
		}	
		/**
		 * When the user selects a section of the text, this method is used to
		 * toggle the defined style on it. If the selected text already has the
		 * style applied, we remove it, otherwise we apply it.
		 * 
		 * @param style
		 *            The styles that should be toggled on the selected text.
		 */
		private void toggleStyle(int style) {
			// Gets the current cursor position, or the starting position of the
			// selection
			int selectionStart = this.getSelectionStart();

			// Gets the current cursor position, or the end position of the
			// selection
			// Note: The end can be smaller than the start
			int selectionEnd = this.getSelectionEnd();

			// Reverse if the case is what's noted above
			if (selectionStart > selectionEnd) {
				int temp = selectionEnd;
				selectionEnd = selectionStart;
				selectionStart = temp;
			}

			// The selectionEnd is only greater then the selectionStart position
			// when the user selected a section of the text. Otherwise, the 2
			// variables
			// should be equal (the cursor position).
			if (selectionEnd > selectionStart) {
				Spannable str = this.getText();
				boolean exists = false;
				StyleSpan[] styleSpans;

				switch (style) {
				case STYLE_BOLD:
					styleSpans = str.getSpans(selectionStart, selectionEnd, StyleSpan.class);

					// If the selected text-part already has BOLD style on it, then
					// we need to disable it
					for (int i = 0; i < styleSpans.length; i++) {
						if (styleSpans[i].getStyle() == android.graphics.Typeface.BOLD) {
							str.removeSpan(styleSpans[i]);
							exists = true;
						}
					}

					// Else we set BOLD style on it
					if (!exists) {
						str.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), selectionStart, selectionEnd,Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
					}

					this.setSelection(selectionStart, selectionEnd);
					break;
				case STYLE_ITALIC:
					styleSpans = str.getSpans(selectionStart, selectionEnd, StyleSpan.class);

					// If the selected text-part already has ITALIC style on it,
					// then we need to disable it
					for (int i = 0; i < styleSpans.length; i++) {
						if (styleSpans[i].getStyle() == android.graphics.Typeface.ITALIC) {
							str.removeSpan(styleSpans[i]);
							exists = true;
						}
					}

					// Else we set ITALIC style on it
					if (!exists) {
						str.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), selectionStart, selectionEnd,Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
					}

					this.setSelection(selectionStart, selectionEnd);
					break;
				case STYLE_UNDERLINED:
					UnderlineSpan[] underSpan = str.getSpans(selectionStart, selectionEnd, UnderlineSpan.class);

					// If the selected text-part already has UNDERLINE style on it,
					// then we need to disable it
					for (int i = 0; i < underSpan.length; i++) {
						str.removeSpan(underSpan[i]);
						exists = true;
					}

					// Else we set UNDERLINE style on it
					if (!exists) {
						str.setSpan(new UnderlineSpan(), selectionStart, selectionEnd, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
					}

					this.setSelection(selectionStart, selectionEnd);
					break;

				case STYLE_COLRED:
					ForegroundColorSpan[] ColorSpan = str.getSpans(selectionStart, selectionEnd, ForegroundColorSpan.class);

					// If the selected text-part already has UNDERLINE style on it,
					// then we need to disable it
					for (int i = 0; i < ColorSpan.length; i++) {
						str.removeSpan(ColorSpan[i]);
						exists = true;
					}

					// Else we set UNDERLINE style on it
					if (!exists) {
						str.setSpan(new ForegroundColorSpan(_myTextColor), selectionStart, selectionEnd, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
					}

					this.setSelection(selectionStart, selectionEnd);
					break;
				}
			}
		}

		/**
		 * This method makes sure that the optional style toggle buttons update
		 * their state correctly when the user moves the cursor around the EditText,
		 * or when the user selects sections of the text.
		 */
		@Override
		public void onSelectionChanged(int selStart, int selEnd) {
			boolean boldExists = false;
			boolean italicsExists = false;
			boolean underlinedExists = false;
			boolean colorExists = false;

			// If the user only placed the cursor around
			if (selStart > 0 && selStart == selEnd) {
				CharacterStyle[] styleSpans = this.getText().getSpans(selStart - 1, selStart, CharacterStyle.class);

				for (int i = 0; i < styleSpans.length; i++) {
					if (styleSpans[i] instanceof StyleSpan) {
						if (((StyleSpan) styleSpans[i]).getStyle() == android.graphics.Typeface.BOLD) {
							boldExists = true;
						} else if (((StyleSpan) styleSpans[i]).getStyle() == android.graphics.Typeface.ITALIC) {
							italicsExists = true;
						} else if (((StyleSpan) styleSpans[i]).getStyle() == android.graphics.Typeface.BOLD_ITALIC) {
							italicsExists = true;
							boldExists = true;
						}
					} else if (styleSpans[i] instanceof UnderlineSpan) {
						underlinedExists = true;

					}else if (styleSpans[i] instanceof ForegroundColorSpan) {
						colorExists = true;
					}

				}
			}

			// Else if the user selected multiple characters
			else {
				CharacterStyle[] styleSpans = this.getText().getSpans(selStart, selEnd, CharacterStyle.class);

				for (int i = 0; i < styleSpans.length; i++) {
					if (styleSpans[i] instanceof StyleSpan) {
						if (((StyleSpan) styleSpans[i]).getStyle() == android.graphics.Typeface.BOLD) {
							if (this.getText().getSpanStart(styleSpans[i]) <= selStart
									&& this.getText().getSpanEnd(styleSpans[i]) >= selEnd) {
								boldExists = true;
							}
						} else if (((StyleSpan) styleSpans[i]).getStyle() == android.graphics.Typeface.ITALIC) {
							if (this.getText().getSpanStart(styleSpans[i]) <= selStart
									&& this.getText().getSpanEnd(styleSpans[i]) >= selEnd) {
								italicsExists = true;
							}
						} else if (((StyleSpan) styleSpans[i]).getStyle() == android.graphics.Typeface.BOLD_ITALIC) {
							if (this.getText().getSpanStart(styleSpans[i]) <= selStart
									&& this.getText().getSpanEnd(styleSpans[i]) >= selEnd) {
								italicsExists = true;
								boldExists = true;
							}
						}
					} else if (styleSpans[i] instanceof UnderlineSpan) {
						if (this.getText().getSpanStart(styleSpans[i]) <= selStart
								&& this.getText().getSpanEnd(styleSpans[i]) >= selEnd) {
							underlinedExists = true;
						}
					}else if (styleSpans[i] instanceof ForegroundColorSpan) {
						if (this.getText().getSpanStart(styleSpans[i]) <= selStart
								&& this.getText().getSpanEnd(styleSpans[i]) >= selEnd) {
							colorExists = true;
						}
					}
				}
			}
			if (_mButtonTextBold != null) {
				if (boldExists){
					_mButtonTextBold.setBackgroundDrawable(_myRes.getDrawable(R.drawable.ic_textbold_selected));
					_myIsTextBoldSelected=true;
				}
				else{
					_mButtonTextBold.setBackgroundDrawable(_myRes.getDrawable(R.drawable.ic_textbold));
					_myIsTextBoldSelected=false;
				}
			}

			if (_mButtonTextItalic != null) {
				if (italicsExists){
					_mButtonTextItalic.setBackgroundDrawable(_myRes.getDrawable(R.drawable.ic_textitalic_selected));
					_myIsTextItalicSelected=true;
				}
				else{
					_mButtonTextItalic.setBackgroundDrawable(_myRes.getDrawable(R.drawable.ic_textitalic));
					_myIsTextItalicSelected=false;
				}
			}

			if (_mButtonTextUnderLine != null) {
				if (underlinedExists){
					_mButtonTextUnderLine.setBackgroundDrawable(_myRes.getDrawable(R.drawable.ic_underline_selected));
					_myIsTextUnderLineSelected=true;
				}
				else{
					_mButtonTextUnderLine.setBackgroundDrawable(_myRes.getDrawable(R.drawable.ic_underline));
					_myIsTextUnderLineSelected=false;
				}
			}
			
			if (colorExists){
				_myLayoutColor.setBackgroundColor(getCurrentHintTextColor());
			}
		}
		//TODO change background selection when text color changes

		// Get and set Spanned, styled text
		public Spanned getSpannedText() {
			return this.getText();
		}

		public void setSpannedText(Spanned text) {
			this.setText(text);
		}

		// Get and set simple text as simple strings
		public String getStringText() {
			return this.getText().toString();
		}

		public void setStringText(String text) {
			this.setText(text);
		}

		// Get and set styled HTML text
		public String getTextHTML() {
			return Html.toHtml(this.getText());
		}

		public void setTextHTML(String text) {
			this.setText(Html.fromHtml(text, null, null));
		}

		public void setLinearColor(LinearLayout pLL){
			_myLayoutColor=pLL;
			_myLayoutColor.setBackgroundColor(Color.BLACK);
		}
		public void setTextBoldButton(Button button) {
			_mButtonTextBold = button;
			_mButtonTextBold.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					toggleStyle(STYLE_BOLD);

					_myIsTextBoldSelected=!_myIsTextBoldSelected;
					if(_myIsTextBoldSelected)
						_mButtonTextBold.setBackgroundDrawable(_myRes.getDrawable(R.drawable.ic_textbold_selected));
					else
						_mButtonTextBold.setBackgroundDrawable(_myRes.getDrawable(R.drawable.ic_textbold));
				}
			});
		}

		public void setTextSizeSpinner(Spinner spinner) {
			_mSpinnerTextSize = spinner;

			String[] lTabTextSize={_myRes.getString(R.string.TextSize_Small),_myRes.getString(R.string.TextSize_Normal),_myRes.getString(R.string.TextSize_big),_myRes.getString(R.string.TextSize_vbig)};
			ArrayAdapter<String> lArrayAdapter = new ArrayAdapter<String>(_myContext, android.R.layout.simple_spinner_item, lTabTextSize);
			lArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
			_mSpinnerTextSize.setAdapter(lArrayAdapter);
			_mSpinnerTextSize.setSelection(1);


			_mSpinnerTextSize.setOnItemSelectedListener(new OnItemSelectedListener() {

				@Override
				public void onItemSelected(AdapterView<?> arg0, View arg1,int arg2, long arg3) {
					Spinner lSpinner=(Spinner) arg0;		
					String lContent=lSpinner.getSelectedItem().toString();

					if(lContent.equals(_myRes.getString(R.string.TextSize_Small)))
						_myTextSize=1;
					else if(lContent.equals(_myRes.getString(R.string.TextSize_Normal)))
						_myTextSize=2;
					else if(lContent.equals(_myRes.getString(R.string.TextSize_big)))
						_myTextSize=3;
					else if(lContent.equals(_myRes.getString(R.string.TextSize_vbig)))
						_myTextSize=4;

					_myIsSizeChaged=true;
				}

				@Override
				public void onNothingSelected(AdapterView<?> arg0) {

				}
			});		
		}

		public void setTextItalicButton(Button button) {
			_mButtonTextItalic = button;
			_mButtonTextItalic.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					toggleStyle(STYLE_ITALIC);

					_myIsTextItalicSelected=!_myIsTextItalicSelected;
					if(_myIsTextItalicSelected)
						_mButtonTextItalic.setBackgroundDrawable(_myRes.getDrawable(R.drawable.ic_textitalic_selected));
					else
						_mButtonTextItalic.setBackgroundDrawable(_myRes.getDrawable(R.drawable.ic_textitalic));
				}
			});
		}
		public void setTextUnderLineButton(Button button) {
			_mButtonTextUnderLine = button;
			_mButtonTextUnderLine.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					toggleStyle(STYLE_UNDERLINED);
					_myIsTextColorSelected=!_myIsTextColorSelected;
					_myIsTextUnderLineSelected=!_myIsTextUnderLineSelected;
					if(_myIsTextUnderLineSelected)
						_mButtonTextUnderLine.setBackgroundDrawable(_myRes.getDrawable(R.drawable.ic_underline_selected));
					else
						_mButtonTextUnderLine.setBackgroundDrawable(_myRes.getDrawable(R.drawable.ic_underline));
				}
			});
		}

		public void setButtonColor(Button button) {
			_mButtonColor = button;
			_mButtonColor.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {


					_mDialogColorPicker.setOnColorPickChangedListener(new OnColorPickChangedListener() {		
						@Override
						public void colorChanged(int color) {
							_myTextColor=color;		
							_myLayoutColor.setBackgroundColor(_myTextColor);
							toggleStyle(STYLE_COLRED);
						}
					});
					_mDialogColorPicker.show();
				}
			});
		}


		public void setTextSizeButton(View button) {
			button.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					_myIsSizeChaged=!_myIsSizeChaged;
				}
			});
		}

		private class DWTextWatcher implements TextWatcher {
			@Override
			public void afterTextChanged(Editable editable) {

				int position = Selection.getSelectionStart(DroidWriterView.this.getText());
				if (position < 0) {
					position = 0;
				}
				if (position > 0) {

								
			     //  editable.setSpan(new RelativeSizeSpan(4), position - 1, position, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);


					CharacterStyle[] appliedStyles = editable.getSpans(position - 1, position, CharacterStyle.class);

					StyleSpan currentBoldSpan = null;
					StyleSpan currentItalicSpan = null;
					UnderlineSpan currentUnderlineSpan = null;
					ForegroundColorSpan currentColorLineSpan = null;


					// Look for possible styles already applied to the entered text
					for (int i = 0; i < appliedStyles.length; i++) {
						if (appliedStyles[i] instanceof StyleSpan) {
							if (((StyleSpan) appliedStyles[i]).getStyle() == android.graphics.Typeface.BOLD) {
								// Bold style 
								currentBoldSpan = (StyleSpan) appliedStyles[i];
							} else if (((StyleSpan) appliedStyles[i]).getStyle() == android.graphics.Typeface.ITALIC) {
								// Italic style 
								currentItalicSpan = (StyleSpan) appliedStyles[i];
							}
						} else if (appliedStyles[i] instanceof UnderlineSpan) {
							// Underlined style
							currentUnderlineSpan = (UnderlineSpan) appliedStyles[i];

						}else if (appliedStyles[i] instanceof ForegroundColorSpan) {

							currentColorLineSpan = (ForegroundColorSpan) appliedStyles[i];
						}
					}

					if (_mButtonTextBold != null) {
						if (_myIsTextBoldSelected && currentBoldSpan == null) {

							editable.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), position - 1, position,Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
						} else if (!_myIsTextBoldSelected && currentBoldSpan != null) {

							int boldStart = editable.getSpanStart(currentBoldSpan);
							int boldEnd = editable.getSpanEnd(currentBoldSpan);

							editable.removeSpan(currentBoldSpan);
							if (boldStart <= (position - 1)) {
								editable.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), boldStart, position - 1,Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
							}

							if (boldEnd > position) {
								editable.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), position, boldEnd,Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
							}
						}
					}

					if (_mButtonTextItalic != null && _myIsTextItalicSelected && currentItalicSpan == null) {
						editable.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), position - 1, position,Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
					} else if (_mButtonTextItalic != null && !_myIsTextItalicSelected && currentItalicSpan != null) {
						int italicStart = editable.getSpanStart(currentItalicSpan);
						int italicEnd = editable.getSpanEnd(currentItalicSpan);

						editable.removeSpan(currentItalicSpan);
						if (italicStart <= (position - 1)) {
							editable.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), italicStart, position - 1,Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
						}

						if (italicEnd > position) {
							editable.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), position, italicEnd,Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
						}
					}

					if (_mButtonTextUnderLine != null &&_myIsTextUnderLineSelected && currentUnderlineSpan == null) {
						editable.setSpan(new UnderlineSpan(), position - 1, position, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
					} else if (_mButtonTextUnderLine != null && !_myIsTextUnderLineSelected && currentUnderlineSpan != null) {
						int underLineStart = editable.getSpanStart(currentUnderlineSpan);
						int underLineEnd = editable.getSpanEnd(currentUnderlineSpan);

						editable.removeSpan(currentUnderlineSpan);
						if (underLineStart <= (position - 1)) {
							editable.setSpan(new UnderlineSpan(), underLineStart, position - 1,Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
						}

						if (underLineEnd > position) {
							editable.setSpan(new UnderlineSpan(), position, underLineEnd,Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
						}
					}

					if (_mButtonColor != null) {			 
						int lColor=_myTextColor;
						if (currentColorLineSpan!=null&& position<editable.length()) 
							lColor=currentColorLineSpan.getForegroundColor();

						editable.setSpan(new ForegroundColorSpan(lColor), position - 1, position, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
					}

				}
			}

			public void beforeTextChanged(CharSequence s, int start, int count, int after) {
			}

			public void onTextChanged(CharSequence s, int start, int before, int count) {
			}
		}

	}